package edu.tgc.service.qrtz;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.ScheduleBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;

import edu.tgc.entity.qrtz.QrtzJob;
import edu.tgc.entity.qrtz.QrtzTrigger;

public class QrtzService {

    protected SchedulerFactory schedulerFactory;

    public void addCronTirgger(QrtzTrigger qrtzTrigger) throws SchedulerException {
        createTrigger(qrtzTrigger, new CronTriggerScheduleBuilder());
    }

    public void addSimpleTirgger(QrtzTrigger qrtzTrigger) throws SchedulerException {
        createTrigger(qrtzTrigger, new SimpleTriggerScheduleBuilder());
    }

    // 清除
    public void clear() {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.clear();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 增加job
    @SuppressWarnings("unchecked")
    public void createJob(QrtzJob qrtzJob) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            JobBuilder jobBuilder = JobBuilder.newJob();
            jobBuilder.ofType((Class<Job>) Class.forName(qrtzJob.getClassName()));
            jobBuilder.withIdentity(qrtzJob.getJobKey());
            jobBuilder.withDescription(qrtzJob.getDescription());
            jobBuilder.requestRecovery(qrtzJob.getRecovery());
            jobBuilder.storeDurably(qrtzJob.getDurable());
            JobDetail jobDetail = jobBuilder.build();
            scheduler.addJob(jobDetail, true, !qrtzJob.getDurable());
        } catch (SchedulerException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public void createTrigger(QrtzTrigger qrtzTrigger, TriggerScheduleBuilder triggerScheduleBuilder) throws SchedulerException {
        TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
        triggerBuilder.withIdentity(qrtzTrigger.getTriggerKey());
        triggerBuilder.withPriority(qrtzTrigger.getPriority()); // 设置优先级
        if (qrtzTrigger.getStartTime() == null) { // 设置开始时间
            triggerBuilder.startNow();
        } else {
            triggerBuilder.startAt(qrtzTrigger.getStartTime());
        }
        triggerBuilder.endAt(qrtzTrigger.getEndTime()); // 结束时间,可以为空
        triggerBuilder.forJob(qrtzTrigger.getJob().getJobKey()); // 针对的作业
        triggerBuilder.withDescription(qrtzTrigger.getDescription()); // 设置描述

        ScheduleBuilder<? extends Trigger> scheduleBuilder = triggerScheduleBuilder.build(qrtzTrigger);
        triggerBuilder.withSchedule(scheduleBuilder);
        Trigger trigger = triggerBuilder.build();
        Scheduler scheduler = this.schedulerFactory.getScheduler();
        if (scheduler.checkExists(qrtzTrigger.getTriggerKey())) {
            scheduler.rescheduleJob(qrtzTrigger.getTriggerKey(), trigger);
        } else {
            scheduler.scheduleJob(trigger);
        }
    }

    // 删除job
    public void deleteJob(QrtzJob qrtzJob) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.deleteJob(qrtzJob.getJobKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    public void deleteTrigger(QrtzTrigger qrtzTrigger) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.unscheduleJob(qrtzTrigger.getTriggerKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回MisfireInstruction列表
     *
     * @return 结果
     * @throws SchedulerException
     *             异常
     */
    public List<Map<String, Object>> getCronMisfireInstructionList() throws SchedulerException {
        List<Map<String, Object>> rv = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("text", "Do Nothing");
        map.put("value", CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
        rv.add(map);
        map = new HashMap<>();
        map.put("text", "Ignore Misfire Policy");
        map.put("value", Trigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY);
        rv.add(map);
        map = new HashMap<>();
        map.put("text", "Smart Policy");
        map.put("value", Trigger.MISFIRE_INSTRUCTION_SMART_POLICY);
        rv.add(map);
        map = new HashMap<>();
        map.put("text", "Fire Once Now");
        map.put("value", CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW);
        rv.add(map);
        return rv;
    }

    /**
     * 返回日历列表
     *
     * @return 结果
     * @throws SchedulerException
     *             异常
     */
    public List<Map<String, Object>> getTimeZoneIdList() {
        List<Map<String, Object>> rv = new ArrayList<>();
        String[] timeZoneIds = TimeZone.getAvailableIDs();
        for (String timeZoneId : timeZoneIds) {
            Map<String, Object> map = new HashMap<>();
            map.put("text", "(UTC+" + TimeZone.getTimeZone(timeZoneId).getRawOffset() + ")" + timeZoneIds);
            map.put("value", timeZoneId);
        }
        return rv;
    }

    // 暂停所有
    public void pause() {
        Scheduler scheduler;
        try {
            scheduler = this.schedulerFactory.getScheduler();
            scheduler.pauseAll();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 暂停trigger
    public void pause(QrtzTrigger qrtzTrigger) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.pauseTrigger(qrtzTrigger.getTriggerKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 暂停job
    public void pauseJob(QrtzJob qrtzJob) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.pauseJob(qrtzJob.getJobKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 恢复所有
    public void resume() {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.resumeAll();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 恢复trigger
    public void resume(QrtzTrigger qrtzTrigger) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.resumeTrigger(qrtzTrigger.getTriggerKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    // 恢复job
    public void resumeJob(QrtzJob qrtzJob) {
        try {
            Scheduler scheduler = this.schedulerFactory.getScheduler();
            scheduler.resumeJob(qrtzJob.getJobKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

}
